﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using AM.Tools;
using FinalTestMachine.Motion;

namespace FinalTestMachine
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        private System.Threading.Mutex mutex;

        private ILog_dll.LogProcessHelper _log = new ILog_dll.LogProcessHelper("异常闪退");

        public App()
        {
            this.Startup += App_Startup;
            this.Startup += new StartupEventHandler(CheckLogin);
            this.Startup += new StartupEventHandler(StartProgram);
            this.Startup += ReadIO;

            this.DispatcherUnhandledException += App_DispatcherUnhandledException;      //UI全局异常未捕获
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; //Task线程未捕获异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; //多线程异常

            AM.Communication.CommunicationCommon.WriteErrToUserEventHandler += s => StaticInitial.Motion.WriteToUser(s, System.Windows.Media.Brushes.Red, false);
            AM.Communication.CommunicationCommon.GetCurrentModePathEventHandler += () => Motion.ParamPath_Motion.SelectedDirPath;

            LanguageManager.LanguageSearchHelper.CreateInstrance();

            RegisterIConncetDLL();
        }

        ~App()
        {
            StopOtherPro();
        }

        public static CardInitialClosedll.CardInitialCloseHelper card = new ZMotionHelper.ZMotionCard("192.168.111.111");

        private void ReadIO(object sender, StartupEventArgs e)
        {
            AM.Core.IO.IOBuilder.Init();
            AM.Core.IO.IOBuilder.IOSetValue(typeof(Motion.IO.StaticIOHelper));
            AM.Core.IO.IOBuild.CylinderBuilder.InitCylinder(typeof(Motion.IO.StaticIOHelper));
        }

        /// <summary>
        /// UI全局异常处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            //可以记录日志并转向错误bug窗口友好提示用户
            var content = "全局UI异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(e.Exception);
            MessageBox.Show(content);
            _log.Write("全局UI异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(e.Exception));
            _log.Write("全局UI异常无法处理基本信息:" + e.Exception.Message + "\r\n" + e.Exception.StackTrace);
            //e.Handled = true;
            // MessageBox.Show("全局UI异常无法处理:" + e.Exception.Message + "\r\n" + e.Exception.StackTrace);
        }

        /// <summary>
        /// Task线程未捕获异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            var content = "全局Task异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(e.Exception);
            MessageBox.Show(content);
            _log.Write("全局Task异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(e.Exception));
            _log.Write("全局Task异常无法处理基本信息:" + e.Exception.Message + "\r\n" + e.Exception.StackTrace);
        }

        /// <summary>
        /// 多线程异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            //可以记录日志并转向错误bug窗口友好提示用户
            if (e.ExceptionObject is System.Exception ex)
            {
                var content = "全局多线程异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(ex);
                MessageBox.Show(content);
                _log.Write("全局多线程异常无法处理详细信息:" + ExceptionHelper.GetInnerExceptionMessageAndStackTrace(ex));
                _log.Write($"全局多线程异常无法处理基本信息:{ex.Message}" + "\r\n" + ex.StackTrace);
                // MessageBox.Show($"全局异常无法处理:{ ex.Message}");
            }
        }

        private void CheckLogin(object sender, StartupEventArgs e)
        {
            Wpf_LoginWnd.LoginMainWnd wnd = new Wpf_LoginWnd.LoginMainWnd();
            bool IsLoginOK = true;
            wnd.LoginFailedEventHanlder += () =>
            {
                IsLoginOK = false;
                this.Shutdown(0);
                Environment.Exit(0);
            };
            wnd.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            wnd.ShowDialog();
        }

        private void App_Startup(object sender, StartupEventArgs e)
        {
            //建立进城单例

            bool ret;
            mutex = new System.Threading.Mutex(true, "WPFDemoMN200", out ret);
            if (!ret)
            {
                MessageBox.Show("Program is open!", "Operation Invalid", MessageBoxButton.OK, MessageBoxImage.Warning);
                Environment.Exit(0);
            }
            //LanguageControlBase.LanguageSearchHelper.CreateInstrance();
        }

        private static List<Process> processesWaitStart = new List<Process>();
        private static object obLock = new object();

        private void StartProgram(object sender, StartupEventArgs e)
        {
            string tmpDirPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "QuickStart");

            if (!System.IO.Directory.Exists(tmpDirPath))
            {
                System.IO.Directory.CreateDirectory(tmpDirPath);
                return;
            }

            string[] pFileName = System.IO.Directory.GetFiles(tmpDirPath);

            Process[] processesRuned = Process.GetProcesses();
            foreach (var item in processesRuned)
            {
                foreach (var item2 in pFileName)
                {
                    string str = System.IO.Path.GetFileNameWithoutExtension(item2);
                    if (str.Contains('.'))
                    {
                        str = str.Split('.')[0];
                    }

                    if (item.ProcessName == str)
                    {
                        item.Kill();
                    }
                }
            }

            foreach (var item in pFileName)
            {
                try
                {
                    processesWaitStart.Add(Process.Start(item));
                }
                catch
                {
                }
            }
        }

        public static void StopOtherPro()
        {
            if (processesWaitStart.Count > 0)
            {
                lock (obLock)
                {
                    if (processesWaitStart.Count > 0)
                    {
                        foreach (var item in processesWaitStart)
                        {
                            try
                            {
                                item.Kill();
                            }
                            catch
                            {
                            }
                        }
                        processesWaitStart.Clear();
                    }
                }
            }
        }

        private static void RegisterIConncetDLL()
        {
            //注册容器，提供窗体创建方式
            IConnectDLL.ConnectManagerHelper.RegisterCreateWindowContainer<TCPHelper3.ConnectClientHelper>(s =>
            {
                var wnd = new TCPHelper3.ClientWindow(s as TCPHelper3.ConnectClientHelper);
                return wnd;
            });

            IConnectDLL.ConnectManagerHelper.RegisterCreateWindowContainer<TCPHelper3.ConnectServerHelper>(s =>
            {
                var wnd = new TCPHelper3.ServerWindow(s as TCPHelper3.ConnectServerHelper);
                return wnd;
            });

            IConnectDLL.ConnectManagerHelper.RegisterCreateWindowContainer<SerialPortDemo3.ConnectSerialPortHelper>(s =>
            {
                var wnd = new SerialPortDemo3.MainWindow(s as SerialPortDemo3.ConnectSerialPortHelper);
                return wnd;
            });

            IConnectDLL.ConnectManagerHelper.RegisterCreateWindowContainer<Power3Demo.ConnectSerialPortHelper>(s =>
            {
                var con = s as Power3Demo.ConnectSerialPortHelper;
                var wnd = new Power3Demo.MainWindow(con, IConnectDLL.ConnectManagerHelper.GetBindingWindowParam(con)[0] as Power3Demo.PowerDataManager);
                return wnd;
            });

            IConnectDLL.ConnectManagerHelper.RegisterCreateWindowContainer<OPTHelper.OPTControlHelper>(s =>
            {
                var wnd = new OPTHelper.Wnd_OPTLight(s as OPTHelper.OPTControlHelper, IConnectDLL.ConnectManagerHelper.GetBindingWindowParam(s)[0] as OPTHelper.ChannelDataManager);
                return wnd;
            });
        }
    }
}